import java.io.Closeable;
import java.io.IOException;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.concurrent.atomic.AtomicBoolean;

public abstract class Connector implements Closeable {
    /**
     * 客户端唯一标识
     */
    private String id;
    private String name;
    private byte clientType;
    private boolean webSocketSign;
    private String ip;
    private int port;
    private String clientAddress;
    private SocketChannel socketChannel;
    private Date lastReadTime;
    private Date lastWriteTime;
    private Date createTime;

    private AtomicBoolean isRead = new AtomicBoolean(false);
    private AtomicBoolean isWrite = new AtomicBoolean(false);
    private int commandAddress;

    public int getCommandAddress() {
        return commandAddress;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public byte getByteCommandAddress() {
        byte result;
        switch (commandAddress) {
            case 10:
                result = (byte) 0x0A;
                break;
            case 11:
                result = (byte) 0x0B;
                break;
            case 12:
                result = (byte) 0x0C;
                break;
            default:
                result = (byte) 0x0D;
                break;
        }
        return result;
    }

    public void setCommandAddress(int commandAddress) {
        this.commandAddress = commandAddress;
    }

    public Connector(boolean webSocketSign) {
        this.webSocketSign = webSocketSign;
        this.lastReadTime = new Date();
        this.lastWriteTime = this.lastReadTime;
        this.createTime = this.lastReadTime;
    }

    public void setUpSocket(SocketChannel socketChannel) throws IOException {
        clientAddress = socketChannel.getRemoteAddress().toString();
        this.socketChannel = socketChannel;
        socketChannel.configureBlocking(false);
        socketChannel.socket().setSoTimeout(1000);
        socketChannel.socket().setPerformancePreferences(1, 3, 3);
        socketChannel.socket().setReceiveBufferSize(16 * 1024);
        socketChannel.socket().setSendBufferSize(16 * 1024);
        socketChannel.socket().setKeepAlive(true);
        socketChannel.socket().setReuseAddress(true);

//        socketChannel.setOption(StandardSocketOptions.SO_RCVBUF, 16 * 1024);
//        socketChannel.setOption(StandardSocketOptions.SO_SNDBUF, 16 * 1024);
//        socketChannel.setOption(StandardSocketOptions.SO_KEEPALIVE, true);
//        socketChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);

//        IoContext context = IoContext.getInstance();
//        SocketChannelAdapter adapter = new SocketChannelAdapter(this.socketChannel, context.getIoProvider(), this);
//        receiver = adapter;
//        receiveDispatcher = new AsyncReceiveDispatcher(receiver, receivePacketCallback);
//
//        // 启动接收
//        receiveDispatcher.start();
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    /**
     * @param clientType 0:设备；1：客户端CS
     */
    public void setClientType(byte clientType) {
        this.clientType = clientType;
    }

    public void setWebSocketSign(boolean webSocketSign) {
        this.webSocketSign = webSocketSign;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public void setClientAddress(String clientAddress) {
        this.clientAddress = clientAddress;
    }

    public void setLastReadTime() {
        setLastReadTime(new Date());
    }

    public void setLastReadTime(Date lastReadTime) {
        if (this.isRead.compareAndSet(false, true)) {
            this.lastReadTime = lastReadTime;
            this.isRead.set(false);
        }
    }

    public void setLastWriteTime() {
        setLastWriteTime(new Date());
    }

    public void setLastWriteTime(Date lastWriteTime) {
        if (this.isWrite.compareAndSet(false, true)) {
            this.lastWriteTime = lastWriteTime;
            this.isWrite.set(false);
        }
    }

    public String getIp() {
        return ip;
    }

    public int getPort() {
        return port;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public byte getClientType() {
        return clientType;
    }

    public boolean isWebSocketSign() {
        return webSocketSign;
    }

    public String getClientAddress() {
        return clientAddress;
    }

    public SocketChannel getSocketChannel() {
        return socketChannel;
    }

    public Date getLastReadTime() {
        return lastReadTime;
    }

    public Date getLastWriteTime() {
        return lastWriteTime;
    }


}
